<?php

/******************************示例start***********************************/
/*
// 执行操作
$operate = isset($_GET['a']) ? $_GET['a'] : 'get';

// 缓存数据的key（缓存文件的名）
$key = isset($_GET['k']) ? $_GET['k'] : 'demo';

// 写入缓存
if($operate == 'set'){
    // 写入的缓存内容
    $data = ['code' => 400, 'msg' => 'fail'];
    // 缓存时间30秒
    $expire = 30;
    // 静态调用set方法写入缓存
    $r = Cachefiles::set($key, $data, $expire);
    var_dump($r);
}
// 读取缓存
if($operate == 'get'){
    // 静态调用get方法写入缓存
    $r = Cachefiles::get($key);
    var_dump($r);
}
// 删除缓存
if($operate == 'del'){
    // 静态调用del方法写入缓存
    $r = Cachefiles::del($key);
    var_dump($r);
}*/

/******************************示例end***********************************/


/**
 * Class Cachefiles数据缓存到文件
 * User: Zhuhaili
 * Date: 2023/11/9
 * Ver: v1.0
 */

class Cachefiles{

    public static $path = './runtime/cache/';
    public static $key = 'demo';
    public static $expire = 0;
    public static $fileFix = '.txt';

    /**
     * Notes: 读取缓存
     * User: ZhuHaili
     * Date: 2023/11/8
     * @param $key
     * @param int $buffer
     * @return bool|string|array|object
     */
    public static function get($key, $buffer = 0){
        $key = $key ? $key : self::$key;
        $file = self::$path.$key.self::$fileFix;
        if(!file_exists($file)){
            return '';
        }
        // 读取文件
        $str = '';
        $fp = fopen($file, "r");
        if(flock($fp, LOCK_SH)) {
            // 分片读取
            if($buffer){
                // 循环读取，读完整个文件
                while(!feof($fp)){
                    // 每次读取 n 字节
                    $str .= fread($fp, $buffer);
                }
            }else{
                // 把整个文件内容读取出来
                $str = fread($fp, filesize($file));
            }
            flock($fp, LOCK_UN);
        }
        fclose($fp);
        // 无内容时删除文件且返回空
        if(!$str){
            unlink($file);
            return '';
        }
        // 判断是否过期
        $expire = (int) substr($str, 0, 10);
        if($expire){
            // 过期删除文件且返回空
            if(time() > filemtime($file) + $expire){
                unlink($file);
                return '';
            }
        }
        // 删除有效时间戳剩下的内容且返回
        $str = unserialize(substr($str, 10));
        return $str;
    }

    /**
     * Notes:写入缓存
     * User: ZhuHaili
     * Date: 2023/11/8
     * @param $key
     * @param $value
     * @param int $expire
     * @return bool
     */
    public static function set($key, $value, $expire = 0){
        if (!is_dir(self::$path)) {
            try {
                mkdir(self::$path, 0755, true);
            } catch (\Exception $e) {
                return false;
            }
        }
        $key = $key ? $key : self::$key;
        $expire = $expire ? $expire : self::$expire;
        $file = self::$path.$key.self::$fileFix;
        $data = str_pad($expire, 10, "0", STR_PAD_LEFT).serialize($value);
        try {
            $fp = fopen($file, "w");
            if (flock($fp, LOCK_EX)) {
                fwrite($fp, $data);
                flock($fp, LOCK_UN);
            }
            fclose($fp);
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Notes:删除缓存
     * User: ZhuHaili
     * Date: 2023/11/8
     * @param $key
     * @return bool
     */
    public static function del($key){
        $key = $key ? $key : self::$key;
        $file = self::$path.$key.self::$fileFix;
        if(file_exists($file)){
            try {
                unlink($file);
            } catch (\Exception $e) {
                return false;
            }
        }
        return true;
    }
}

